/**
 * Copyright(c) 2010 Ceno Techonologies Co., Ltd.
 *
 * History:
 *   15-4-20 上午11:51 Created by lyyang
 */
package com.xunton.bss.weixin.api.token;

import javax.inject.Inject;
import javax.inject.Named;

import com.jade.framework.base.util.HttpUtils;
import com.jade.framework.cache.CacheService;
import com.xunton.bss.weixin.api.WeixinException;
import com.xunton.bss.weixin.api.token.pdu.AccessToken;
import com.xunton.bss.weixin.api.token.pdu.ApiTicket;
import com.xunton.bss.weixin.api.token.pdu.UserAccessToken;


/**
 * 微信令牌管理器
 *
 * @author <a href="mailto:lyyang@ceno.cn">lyyang</a>
 * @version 1.0 15-4-20 上午11:51
 */
@Named ("weixin_tokenAgent")
public class TokenAgent
{
    private final static String KEY_ACCESS_TOKEN = "ags_weixin_access_token";
    private final static String KEY_API_TICKET = "ags_weixin_api_ticket";
    private CacheService cacheService;
    private String serverUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
    private String apiTicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=wx_card&access_token=";
    private String defaultSecret = "e63e47ce92a53fc2b65fd0b03b214ab4";
    private String defaultAppId = "wx6ed3ee6bdcd70fa0";
    private int timeOut = 7000;

    @Inject
    public void setCacheService(@Named ("system_cacheService") CacheService cacheService)
    {
        this.cacheService = cacheService;
    }

    public synchronized String getAccessToken()
            throws Exception
    {
        return getAccessToken(defaultAppId, defaultSecret);

    }

    public UserAccessToken getUserAccessToken(String code)
            throws Exception
    {
        return getUserAccessToken(defaultAppId, defaultSecret, code);
    }

    public synchronized String getAccessToken(String appId, String secret)
            throws Exception
    {
        String token = cacheService.get(KEY_ACCESS_TOKEN + "_" + appId);
        if (token == null) {
            String url = serverUrl + "&appid=" + appId + "&secret=" + secret;
            AccessToken accessToken = HttpUtils.getHttp(url, AccessToken.class);
            if (accessToken == null) {
                throw new WeixinException("err.ags.weixin.api.token.not_found", "access token not found");
            }
            if (accessToken.getErrorCode() != 0) {
                throw new WeixinException("err.ags.weixin.api.token.get",
                        "Can't get access token:" + accessToken.getErrorCode() + "," + accessToken.getErrorMsg());
            }
            token = accessToken.getToken();
            timeOut = timeOut < accessToken.getExpires() ? timeOut : accessToken.getExpires();
            cacheService.set(KEY_ACCESS_TOKEN + "_" + appId, token, timeOut);
        }
        return token;

    }

    public UserAccessToken getUserAccessToken(String appId, String secret, String code)
            throws Exception
    {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code";
        return HttpUtils.getHttp(url, UserAccessToken.class);

    }

    public String getApiTicket(String accessToke)
            throws Exception
    {
        String ticket = cacheService.get(KEY_API_TICKET + "_" + accessToke);
        if (ticket == null) {
            String url = apiTicketUrl + accessToke;
            ApiTicket response = HttpUtils.getHttp(url, ApiTicket.class);
            if (response == null) {
                throw new WeixinException("err.ags.weixin.api.token.ticket_not_found", "access token not found");
            }
            if (response.getErrorCode() != 0) {
                throw new WeixinException("err.ags.weixin.api.token.get_ticket",
                        "Can't get api ticket:" + response.getErrorCode() + "," + response.getErrorMsg());
            }
            ticket = response.getTicket();
            timeOut = timeOut < response.getExpiresIn() ? timeOut : response.getExpiresIn();
            cacheService.set(KEY_API_TICKET + "_" + accessToke, ticket, timeOut);
        }
        return ticket;
    }

    public String getServerUrl()
    {
        return serverUrl;
    }

    public void setServerUrl(String serverUrl)
    {
        this.serverUrl = serverUrl;
    }

    public String getDefaultSecret()
    {
        return defaultSecret;
    }

    public void setDefaultSecret(String defaultSecret)
    {
        this.defaultSecret = defaultSecret;
    }

    public String getDefaultAppId()
    {
        return defaultAppId;
    }

    public void setDefaultAppId(String defaultAppId)
    {
        this.defaultAppId = defaultAppId;
    }

    public int getTimeOut()
    {
        return timeOut;
    }

    public void setTimeOut(int timeOut)
    {
        this.timeOut = timeOut;
    }
}
